using System;
using System.Drawing;
using System.Collections.Generic;

namespace PinTuGame
{
    /// <summary>
    /// 拼图游戏核心逻辑类
    /// </summary>
    public class PuzzleGame
    {
        // 游戏状态
        public enum GameState
        {
            Ready,
            Playing,
            Paused,
            Completed
        }

        // 游戏难度级别
        public enum Difficulty
        {
            Easy,     // 10x10
            Medium,   // 20x20
            Hard,     // 30x30
            Extreme,  // 40x40
            Insane    // 50x50
        }

        private int[,] board;
        private int size;
        private int emptyPosX;
        private int emptyPosY;
        private DateTime startTime;

        // 当前游戏状态
        public GameState CurrentState { get; private set; }
        
        // 当前难度
        public Difficulty CurrentDifficulty { get; private set; }
        
        // 原始图片
        public Image OriginalImage { get; private set; }
        
        // 拼图碎片列表
        public List<Image> PuzzlePieces { get; private set; }
        
        // 游戏计时器
        public TimeSpan PlayTime => DateTime.Now - startTime;
        
        // 移动步数
        public int MoveCount { get; private set; }

        public PuzzleGame(Difficulty difficulty)
        {
            CurrentDifficulty = difficulty;
            size = GetSizeFromDifficulty(difficulty);
            board = new int[size, size];
            CurrentState = GameState.Ready;
            PuzzlePieces = new List<Image>();
        }

                 /// <summary>
         /// 初始化新游戏
         /// </summary>
         public void NewGame(Image image)
         {
             OriginalImage = image;
             InitializeBoard();
             SplitImage();
             Shuffle();
             MoveCount = 0;
             startTime = DateTime.Now;
             CurrentState = GameState.Playing;
         }
 
         /// <summary>
         /// 初始化新游戏（不打乱）
         /// </summary>
         public void NewGameWithoutShuffle(Image image)
         {
             OriginalImage = image;
             InitializeBoard();
             SplitImage();
             // 不打乱，保持有序状态
             MoveCount = 0;
             startTime = DateTime.Now;
             CurrentState = GameState.Playing;
         }

        private int GetSizeFromDifficulty(Difficulty difficulty)
        {
            return difficulty switch
            {
                Difficulty.Easy => 10,
                Difficulty.Medium => 20,
                Difficulty.Hard => 30,
                Difficulty.Extreme => 40,
                Difficulty.Insane => 50,
                _ => 10
            };
        }

        private void InitializeBoard()
        {
            int value = 1;
            for (int y = 0; y < size; y++)
            {
                for (int x = 0; x < size; x++)
                {
                    board[x, y] = value++;
                }
            }
            // 不再设置空白格，所有位置都有值
        }
        
        public void Shuffle()
        {
            Random rand = new Random();
            int totalPieces = size * size;
            
            // 使用新的交换逻辑进行打乱
            for (int i = 0; i < totalPieces * 20; i++)
            {
                int index1 = rand.Next(totalPieces);
                int index2 = rand.Next(totalPieces);
                
                // 直接交换两个随机位置的碎片
                if (index1 != index2)
                {
                    int x1 = index1 % size;
                    int y1 = index1 / size;
                    int x2 = index2 % size;
                    int y2 = index2 / size;
                    
                    int temp = board[x1, y1];
                    board[x1, y1] = board[x2, y2];
                    board[x2, y2] = temp;
                }
            }
            MoveCount = 0;
        }

        /// <summary>
        /// 尝试按指定方向移动拼图碎片
        /// </summary>
        /// <param name="direction">0:上, 1:右, 2:下, 3:左</param>
        /// <returns>是否移动成功</returns>
        public bool TryMove(int direction)
        {
            if (CurrentState != GameState.Playing) return false;
            
            int newX = emptyPosX;
            int newY = emptyPosY;
            
            // 计算目标位置
            switch(direction)
            {
                case 0: newY--; break; // 上
                case 1: newX++; break; // 右
                case 2: newY++; break; // 下
                case 3: newX--; break; // 左
            }
            
            // 检查边界
            if (newX < 0 || newX >= size || newY < 0 || newY >= size)
                return false;
            
            // 执行移动
            board[emptyPosX, emptyPosY] = board[newX, newY];
            board[newX, newY] = 0;
            emptyPosX = newX;
            emptyPosY = newY;
            MoveCount++;
            
            return true;
        }
        
        /// <summary>
        /// 交换两个拼图碎片的位置（新规则：任意两个碎片都可以交换）
        /// </summary>
        public bool SwapPieces(int index1, int index2)
        {
            int x1 = index1 % size;
            int y1 = index1 / size;
            int x2 = index2 % size;
            int y2 = index2 / size;
            
            // 新规则：任意两个碎片都可以交换，不需要相邻
            if (index1 != index2)
            {
                int temp = board[x1, y1];
                board[x1, y1] = board[x2, y2];
                board[x2, y2] = temp;
                
                MoveCount++;
                return true;
            }
            return false;
        }

        /// <summary>
        /// 检查游戏是否完成
        /// </summary>
        public bool CheckCompletion()
        {
            int value = 1;
            for (int y = 0; y < size; y++)
            {
                for (int x = 0; x < size; x++)
                {
                    if (board[x, y] != value++) return false;
                }
            }
            CurrentState = GameState.Completed;
            return true;
        }

        /// <summary>
        /// 分割图片为拼图碎片
        /// </summary>
        private void SplitImage()
        {
            if (OriginalImage == null) return;
            
            PuzzlePieces.Clear();
            int pieceWidth = OriginalImage.Width / size;
            int pieceHeight = OriginalImage.Height / size;

            for (int y = 0; y < size; y++)
            {
                for (int x = 0; x < size; x++)
                {
                    Rectangle rect = new Rectangle(
                        x * pieceWidth,
                        y * pieceHeight,
                        pieceWidth,
                        pieceHeight);

                    Bitmap piece = new Bitmap(pieceWidth, pieceHeight);
                    using (Graphics g = Graphics.FromImage(piece))
                    {
                        g.DrawImage(OriginalImage, 0, 0, rect, GraphicsUnit.Pixel);
                    }
                    PuzzlePieces.Add(piece);
                }
            }
        }

        public int[,] GetBoard() => board;
        public Image GetPieceImage(int index) => PuzzlePieces[index];

        /// <summary>
        /// 检查指定索引的碎片是否在正确位置
        /// </summary>
        /// <param name="index">碎片索引</param>
        /// <returns>是否在正确位置</returns>
        public bool IsPieceInCorrectPosition(int index)
        {
            int x = index % size;
            int y = index / size;
            int expectedValue = y * size + x + 1;
            
            return board[x, y] == expectedValue;
        }

        /// <summary>
        /// 获取指定位置应该放置的碎片值
        /// </summary>
        /// <param name="x">X坐标</param>
        /// <param name="y">Y坐标</param>
        /// <returns>应该放置的碎片值</returns>
        public int GetExpectedValue(int x, int y)
        {
            return y * size + x + 1;
        }
    }
}